'use strict';

const path = require('path')
const pkgDir = require('pkg-dir').sync
const npminstall = require('npminstall')
const fse = require('fs-extra')
const pathExists = require('path-exists').sync
const { isObject } = require('@ayuan-cli/util')
const formatPath = require('@ayuan-cli/format-path')
const { getDefaultRegistry, getLatestNpmVersions } =require('@ayuan-cli/get-npm-info')

class Package {
    constructor(options) {
        if (!options) {
            throw new Error('Package 类 options 配置参数不能未空！')
        }
        if (!isObject(options)) {
            throw new Error('Package 类 options 配置参数必须是对象！')
        }
        this.targetPath = options.targetPath
        this.packageName = options.packageName
        this.packageVersion = options.packageVersion
        this.storeDir = options.storeDir
        this.packageFilePathPrefix = this.packageName.replace('/', '_')
    }
    async prepare() {
        if (this.storeDir && !pathExists(this.storeDir)) {
            fse.mkdirpSync(this.storeDir) // 创建路径
        }
        if (this.packageVersion ==="latest") {
            this.packageVersion = await getLatestNpmVersions(this.packageName)
        }
    }

    // 实时生成路径
    get cacheFilePath() {
        return path.resolve(this.storeDir, `_${this.packageFilePathPrefix}@${this.packageVersion}@${this.packageName}`)
    }

    getSpecificFilePath(packageVersion) {
        return path.resolve(this.storeDir, `_${this.packageFilePathPrefix}@${packageVersion}@${this.packageName}`)
    }

    async exists() {
        await this.prepare()
        if (this.storeDir) {
            return pathExists(this.cacheFilePath)
        } else {
            return pathExists(this.targetPath)
        }
    }

    install() {
         return  npminstall({
            root: this.targetPath,
            storeDir: this.storeDir,
            registry: getDefaultRegistry(),
            pkgs: [
                { name: this.packageName, version: this.packageVersion }
            ]
        })
    }

    async update() {
        await this.prepare()
        const packageLatestVersion = await getLatestNpmVersions(this.packageName)
        const latestFilePath = this.getSpecificFilePath(packageLatestVersion)
        if(!pathExists(latestFilePath)){
            this.packageVersion = packageLatestVersion
            return await npminstall({
                root: this.targetPath,
                storeDir: this.storeDir,
                registry: getDefaultRegistry(),
                pkgs: [
                    { name: this.packageName, version: this.packageVersion }
                ]
            })
        }
    }

     async getRootFilePath() {
         this.packageVersion = await getLatestNpmVersions(this.packageName)
         function _getRootFilePath(targetPath) {
            const dir =  pkgDir(targetPath)
            if (dir) {
                // 寻找 package.json
                const pkgFile = require(path.join(dir,'package.json'))
                if (pkgFile && pkgFile.main) {
                    // formatPath 路径兼容（window 和 mac）
                    return formatPath(path.resolve(dir, pkgFile.main))
                }
            }
            return null
        }
        if (this.storeDir) {
            return _getRootFilePath(this.cacheFilePath)
        } else {
            return _getRootFilePath(this.targetPath)
        }
    }
}

module.exports = Package;


